package cn.edu.zut.score.service.impl;

import cn.edu.zut.score.core.cache.RedisCache;
import cn.edu.zut.score.core.constant.MessageTypeEnum;
import cn.edu.zut.score.core.constant.ReplyInfoStatus;
import cn.edu.zut.score.core.convert.MessageConvert;
import cn.edu.zut.score.core.domain.PageResponse;
import cn.edu.zut.score.core.domain.RestResponse;
import cn.edu.zut.score.core.dto.request.MessagePageRequest;
import cn.edu.zut.score.core.dto.response.MessageResponse;
import cn.edu.zut.score.core.entity.Message;
import cn.edu.zut.score.core.entity.ReplyInfo;
import cn.edu.zut.score.core.entity.User;
import cn.edu.zut.score.mapper.MessageMapper;
import cn.edu.zut.score.service.IMessageService;
import cn.edu.zut.score.service.IReplyInfoService;
import cn.edu.zut.score.service.IUserService;
import cn.edu.zut.score.service.biz.WebSocketService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zby
 * @since 2021-06-25
 */
@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements IMessageService {

    @Autowired
    private RedisCache redisCache;

    @Autowired(required = false)
    private HttpServletRequest httpServletRequest;

    @Autowired(required = false)
    private MessageMapper messageMapper;

    @Autowired
    private IReplyInfoService iReplyInfoService;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private WebSocketService webSocketService;

    @Override
    public Map<Long, Long> addMessage(String title, String content, Integer type, List<Long> receiveIds) {
        Map<Long, Long> res = new HashMap<>();
        for (Long receiveId : receiveIds) {
            Message message = new Message();
            message.setType(type);
            message.setTitle(title);
            message.setContent(content);
            message.setReceiveId(receiveId);
            message.setIsRead(0);
            message.fillCreateInfo(httpServletRequest, redisCache);
            this.saveOrUpdate(message);
            res.put(message.getId(), receiveId);
        }
        return res;
    }

    @Override
    public RestResponse<PageResponse<MessageResponse>> getMessages(MessagePageRequest messagePageRequest) {
        Page<Message> page = new Page<>(messagePageRequest.getPage(), messagePageRequest.getLimit());
        LambdaQueryWrapper<Message> qw = new LambdaQueryWrapper<>();
        if (messagePageRequest.getType() != null) {
            qw.eq(Message::getType, messagePageRequest.getType());
        }
        if (messagePageRequest.getIsRead() != null && messagePageRequest.getIsRead() != -1) {
            qw.eq(Message::getIsRead, messagePageRequest.getIsRead());
        }
        String token = httpServletRequest.getHeader("Authorization");
        User currentUser = redisCache.getCurrentUser(token);
        qw.eq(Message::getReceiveId, currentUser.getId());
        qw.orderByDesc(Message::getId);
        IPage<Message> pageData = messageMapper.selectPage(page, qw);
        List<Message> records = pageData.getRecords();
        List<MessageResponse> messageResponses = MessageConvert.INSTANCE.messages2Responses(records);
        return RestResponse.success(new PageResponse<>(messageResponses, pageData.getTotal(), messagePageRequest.getPage(), messagePageRequest.getLimit()));
    }

    @Override
    public RestResponse<String> pushMarkMessage(Long replyId, Long studentId) {
        LambdaQueryWrapper<ReplyInfo> qw = new LambdaQueryWrapper<>();
        qw.eq(ReplyInfo::getReplyId, replyId);
        qw.eq(ReplyInfo::getStudentId, studentId);
        ReplyInfo replyInfo = new ReplyInfo();
        replyInfo.setStatus(ReplyInfoStatus.over.getCode());
        replyInfo.fillUpdateInfo(httpServletRequest, redisCache);
        iReplyInfoService.update(replyInfo, qw);

        List<Long> receiveIds = iReplyInfoService.getReplyUserIdsByReplyId(replyId, studentId);
        User student = iUserService.getById(studentId);
        String title = "请为" + student.getName() + "评分";
        String content = replyId + "" + student.getId() + student.getName() + "的精彩答辩结束了，请你为" + (student.getGender() == 0 ? "她" : "他") + "评分（三十分钟内有效）：";
        Map<Long, Long> addMessage = addMessage(title, content, MessageTypeEnum.mark.getCode(), receiveIds);
        webSocketService.sendAssignMessage(student.getName(), addMessage);
        return RestResponse.success("成功");
    }

    @Override
    public RestResponse<String> setRead(Long messageId) {
        LambdaQueryWrapper<Message> qw = new LambdaQueryWrapper<>();
        qw.eq(Message::getId, messageId);
        Message message = new Message();
        message.setIsRead(1);
        message.fillUpdateInfo(httpServletRequest, redisCache);
        messageMapper.update(message, qw);
        return RestResponse.success("成功");
    }

    @Override
    public Integer getrUnReadNumById(Long userId) {
        LambdaQueryWrapper<Message> qw = new LambdaQueryWrapper<>();
        qw.eq(Message::getReceiveId, userId);
        qw.eq(Message::getIsRead, 0);
        return messageMapper.selectCount(qw);
    }
}
